package tp1_Model;

import java.util.ArrayList;
import java.util.List;

import org.uqbar.commons.model.ObservableObject;

import tp1.Casillero;
import tp1.Esfera;
import tp1.Personaje;
import tp1.Punto;

/**
 * @author martin
 * 
 */
public class Mapa extends ObservableObject {
	private static Mapa INSTANCE = null;
	public static final String PUEDEIR = "puedeIr";
	public static final String PERSONAJE = "personaje";
	public static final String ESFERA = "esfera";
	public static final String NUEVOPERSONAJE = "nuevoObjeto";
	public static final String CASILLERO = "casillero";
	public static final String CASILLEROS = "casilleros";
	public static final String RESISTENCIA = "resistencia";
	public static final String LBLNOMBRE = "lblnombre";
	public static final String LBLCASILLERO = "lblcasillero";
	public static final String LBLRESISTENCIA = "lblresistencia";
	public static final String SELPERSONAJE = "selpersonaje";
	public static final String SELESFERA = "selesfera";
	public static final String ACTUALROW = "actualrow";
	public static final String ESFERASENELMAPA = "esferasEnElMapa";
	public static final String PERSONAJESENELMAPA = "personajesEnElMapa";
	public static final String RESPUESTASHENGLONG = "respuestashenglong";
	public static final String CALCULARDISTANCIA = "calcularDistancia";
	public static final String AGREGARESFERAAPERSONAJE = "agregarEsferaAPersonaje";
	public static final String GRABAROBJETO = "grabarObjeto";
	public static final String LLAMARASHENGLONG = "llamarAShengLong";

	private List<Casillero> casilleros = new ArrayList<Casillero>();
	private String puedeIr = "                                                                                      ";
	private Personaje personaje;
	private Esfera esfera;
	private String nuevoObjeto;
	private int casillero;
	private int resistencia;
	private String lblnombre = "Nombre :";
	private String lblcasillero = "Casillero :";
	private String lblresistencia = "Resistencia :";
	private Boolean selpersonaje;
	private Boolean selesfera;
	private String queSeCrea;
	private Casillero actualrow;
	private String buttoncrearpersonaje;
	private List<Personaje> personajesEnElMapa = new ArrayList<Personaje>();
	private List<Esfera> esferasEnElMapa = new ArrayList<Esfera>();
	private String respuestashenglong = "                                                                                                             ";
	private Boolean botonDeRespuestaAShengLong = false;
	private int cantidadx;
	private int cantidady;
	
	private List<Integer> numerosEsfera = new ArrayList<Integer>();

	public List<Integer> getNumerosEsfera() {
		return numerosEsfera;
	}

	public void setNumerosEsfera(List<Integer> numerosEsfera) {
		this.numerosEsfera = numerosEsfera;
	}

	public static Mapa getInstance() {
		if (INSTANCE == null) {
			INSTANCE = new Mapa(10);
		}
		return INSTANCE;
	}

	public String getRespuestashenglong() {
		return respuestashenglong;
	}

	public Boolean getButrespsheng() {
		return botonDeRespuestaAShengLong;
	}

	public void setButrespsheng(Boolean butrespsheng) {
		this.setProperty("botrespsheng", butrespsheng);
	}

	public void setRespuestashenglong(String respuestashenglong) {
		this.setProperty("respuestashenglong", respuestashenglong);
		// this.respuestashenglong = respuestashenglong;
	}

	public List<Esfera> getEsferasEnElMapa() {
		return esferasEnElMapa;
	}

	public void setEsferasEnElMapa(List<Esfera> esferasEnElMapa) {
		// this.esferasEnElMapa = esferasEnElMapa;
		this.setProperty("esferasEnElMapa", esferasEnElMapa);
		// this.firePropertyChange("esferasEnElMapa", null,
		// this.getEsferasEnElMapa());
	}

	public List<Personaje> getPersonajesEnElMapa() {
		return personajesEnElMapa;
	}

	public void setPersonajesEnElMapa(List<Personaje> personajesEnElMapa) {
		this.personajesEnElMapa = personajesEnElMapa;
	}

	public String getButtoncrearpersonaje() {
		return buttoncrearpersonaje;
	}

	public void setButtoncrearpersonaje(String buttoncrearpersonaje) {
		this.buttoncrearpersonaje = buttoncrearpersonaje;
	}

	public Casillero getActualrow() {
		return actualrow;
	}

	public void setActualrow(Casillero actualrow) {
		this.setProperty("actualrow", actualrow);
	}

	public Boolean getSelpersonaje() {
		return selpersonaje;
	}

	public void setSelpersonaje(Boolean selpersonaje) {
		this.setProperty("selpersonaje", selpersonaje);
		this.setQueSeCrea("P");
		this.setProperty("selesfera", !selpersonaje);
	}

	public Boolean getSelesfera() {
		return selesfera;
	}

	public void setSelesfera(Boolean selesfera) {
		this.setProperty("selesfera", selesfera);
		this.setQueSeCrea("E");
		this.setProperty("selpersonaje", !selesfera);
	}

	public String getQueSeCrea() {
		return queSeCrea;
	}

	public void setQueSeCrea(String queSeCrea) {
		this.queSeCrea = queSeCrea;
	}

	public Boolean getSelobjeto() {
		return selpersonaje;
	}

	public void setSelobjeto(Boolean selobjeto) {
		this.selpersonaje = selobjeto;
	}

	public String getLblresistencia() {
		return lblresistencia;
	}

	public void setLblresistencia(String lblresistencia) {
		this.lblresistencia = lblresistencia;
	}

	public String getLblcasillero() {
		return lblcasillero;
	}

	public void setLblcasillero(String lblcasillero) {
		this.lblcasillero = lblcasillero;
	}

	public void setLblnombre(String lblnombre) {
		this.lblnombre = lblnombre;
	}

	public int getCasillero() {
		return casillero;
	}

	public void setCasillero(int casillero) {
		this.casillero = casillero;
	}

	public String getLblnombre() {
		return lblnombre;
	}

	public void setLblNombre(String lblnombre) {
		this.lblnombre = lblnombre;
	}

	public String getNuevoObjeto() {
		return nuevoObjeto;
	}

	public void setNuevoObjeto(String nuevoObjeto) {
		this.nuevoObjeto = nuevoObjeto;
	}

	public Esfera getEsfera() {
		return esfera;
	}

	public void setEsfera(Esfera esfera) {
		this.setProperty(ESFERA, esfera);
	}

	public Personaje getPersonaje() {
		return personaje;
	}

	public void setPersonaje(Personaje personaje) {
		this.setProperty(PERSONAJE, personaje);
	}

	public String getPuedeIr() {
		return puedeIr;
	}

	public void setPuedeIr(String puedeIr) {
		this.setProperty(PUEDEIR, puedeIr);
	}

	/**
	 * Este método se encarga de crear un mapa con n cantidad de casilleros
	 * distribuidos alrededor del mapa.
	 * 
	 * @param cantidadDeCasilleros
	 * 
	 */
	public Mapa(int cantidadDeCasilleros) {
		for (int i = 0; i < cantidadDeCasilleros; i++) {
			this.getCasilleros().add(new Casillero(i));
		}

		// Crea los personajes que iran en el tablero //
		Personaje per1 = new Personaje("Goku                                                                                                                     ", 50,
				"images/goku.png");
		Personaje per2 = new Personaje("Picolo", 25, "images/acatos.png");
		Personaje per3 = new Personaje("Vegeta", 1, "images/veggetta.png");
		this.getPersonajesEnElMapa().add(per1);
		this.getPersonajesEnElMapa().add(per2);
		this.getPersonajesEnElMapa().add(per3);

		this.getCasilleros().get(0).agregarPersonaje(per1);
		this.getCasilleros().get(5).agregarPersonaje(per2);
		this.getCasilleros().get(7).agregarPersonaje(per3);

		// ///////////////////////////////////////////////

		// Se crea la lista de personajes para luego pasarla por
		// parametro //

		// Crea la lista de esferas que existen en el tablero
		Esfera es1 = new Esfera("2                                                  ", "esfera1.png");
		Esfera es2 = new Esfera("1", "esfera2.png");
		Esfera es3 = new Esfera("3", "esfera1.png");
		Esfera es4 = new Esfera("4", "esfera2.png");
		this.getEsferasEnElMapa().add(es1);
		this.getEsferasEnElMapa().add(es2);
		this.getEsferasEnElMapa().add(es3);
		this.getEsferasEnElMapa().add(es4);
		// ////////////////////////////
		per1.getEsferas().add(es1);
		per1.getEsferas().add(es2);
		per1.getEsferas().add(es3);
		per1.getEsferas().add(es4);
		this.getCasilleros().get(2).agregarEsfera(es1);
		this.getCasilleros().get(4).agregarEsfera(es2);
		this.getCasilleros().get(6).agregarEsfera(es3);
		this.getCasilleros().get(8).agregarEsfera(es4);

	}

	public List<Casillero> getCasilleros() {
		return casilleros;
	}

	public void setCasilleros(List<Casillero> casilleros) {
		this.setProperty(CASILLEROS, casilleros);
	}

	public void moverPersonajeAunPunto(Personaje personaje, Punto punto) {

	}

	public List<Personaje> getPersonajes() {
		List<Personaje> personajes = new ArrayList<Personaje>();
		for (Casillero casillero : this.getCasilleros()) {
			if (!casillero.isEmpty() && !(casillero.getPersonaje() == null)) {
				personajes.add(casillero.getPersonaje());
			}

		}
		return personajes;
	}

	public List<Esfera> getEsferas() {
		List<Esfera> esferas = new ArrayList<Esfera>();
		for (Casillero casillero : this.getCasilleros()) {
			if (!casillero.isEmpty()) {
				esferas.add(casillero.getEsfera());
			}
		}
		return esferas;
	}

	public int getResistencia() {
		return resistencia;
	}

	public void setResistencia(int resistencia) {
		this.resistencia = resistencia;
	}

	public int distancia() {
		int num1 = this.getPersonaje().getPosicion();
		int num2 = this.getEsfera().getPosicion();
		return Math.abs(num1 - num2);

	}

	public void calcularDistancia() {
		int res = this.distancia();

		if (this.getPersonaje().puedeRecorrer(res)) {
			this.setPuedeIr("Si, soy sumamente resistente");
		} else {
			this.setPuedeIr("No, estoy viejo y el cuerpo ya no me da");
		}
	}

	public void grabarObjeto() {
		int numcasillero;
		if (!(this.getActualrow() == null)) {
			numcasillero = this.getActualrow().getPosicion();
		} else {
			numcasillero = this.getCasillero();
		}
		if (this.getQueSeCrea() == "P") {
			Personaje personaje = new Personaje(this.getNuevoObjeto(), this.getResistencia(), "");
			this.getCasilleros().get(numcasillero).agregarPersonaje(personaje);
			this.getPersonajesEnElMapa().add(personaje);
			this.firePropertyChange(PERSONAJESENELMAPA, null, this.getPersonajesEnElMapa());
		} else {
			Esfera esfera = new Esfera(this.getNuevoObjeto(), "");
			this.getCasilleros().get(numcasillero).agregarEsfera(esfera);
			this.getEsferasEnElMapa().add(esfera);
			List<Esfera> actualizada = new ArrayList<Esfera>();
			actualizada.addAll(this.getEsferasEnElMapa());
			this.setEsferasEnElMapa(actualizada);
			this.firePropertyChange(ESFERASENELMAPA, null, this.getEsferasEnElMapa());
		}
		this.firePropertyChange(CASILLEROS, null, this.getCasilleros());
		this.firePropertyChange(PERSONAJE, null, this.getPersonaje());
		this.firePropertyChange(ESFERA, null, this.getEsfera());
	}

	public void agregarEsferaAPersonaje() {
		if (this.getPersonaje().puedeRecorrer(this.distancia())) {
			this.getPersonaje().irACasillero(this.getCasilleros().get(this.getEsfera().getCasillero().getPosicion()), this.distancia());
			this.getPersonaje().juntarEsfera(this.getEsfera());
		} else {
			this.setPuedeIr("No, estoy viejo y el cuerpo ya no me da");
		}
		this.firePropertyChange(CASILLEROS, null, this.getCasilleros());

	}

	public void llamarAShengLong() {
		if (!(this.getPersonaje() == null)) {
			if (this.getPersonaje().cantidadDeEsferas() >= 7) {
				this.setRespuestashenglong("Sheng Long Atendió el telefono");
			} else {
				this.setRespuestashenglong("No has conseguido el numero de sheng long aun");
			}
		}

	}

	public Object getSelected() {
		// TODO Auto-generated method stub
		return null;
	}
	
	public void CrearEsferaEn(Esfera unaEsfera, int casillero) {
		Casillero casi = this.getCasilleros().get(casillero);
		casi.agregarEsfera(unaEsfera);
		this.getNumerosEsfera().add(unaEsfera.getNumeroNombre());
	}

	public void CrearPersonajeEn(Personaje personaje, int casillero) {
		this.getCasilleros().get(casillero).agregarPersonaje(personaje);
	}
	
	public Boolean numEstaDisponible(int n, List<Integer> numEsf){
		for (Integer i : numEsf) {
			if(i == n){
				return true;
			}
		}
		return false;
	}
	
	public List<Integer> numerosEsferaLibres(){
		List<Integer> numerosDisponibles = new ArrayList<Integer>();
		for(int i = 1; i <= 7; i++){
			if(!this.numEstaDisponible(i, this.getNumerosEsfera())){
				numerosDisponibles.add(i);
			}
		}
		return numerosDisponibles;
	}

	public List<Integer> casillerosLibres() {
		List<Integer> casillerosVacio = new ArrayList<Integer>();
		for (Casillero casillero : this.getCasilleros()) {
			if (casillero.getPersonaje() == null) {
				casillerosVacio.add(casillero.getPosicion());
			}

		}

		return casillerosVacio;

	}
	

//	public void CrearEsferaEn(Esfera unaEsfera, Integer casillero2) {
//		this.getCasilleros().get(casillero).agregarEsfera(unaEsfera);
//	}

}
